/**
 * LLM服务层
 * 处理与通义千问的交互逻辑
 */
const llmClient = require('../utils/llm-client');
const { log } = require('../middleware/logger');

class LLMService {
  constructor() {
    this.conversationContexts = new Map(); // 存储对话上下文
  }

  /**
   * 处理用户消息
   * @param {string} message - 用户消息
   * @param {string} conversationId - 对话ID
   * @param {Array} availableTools - 可用工具列表
   * @returns {Promise<Object>} 处理结果
   */
  async processMessage(message, conversationId, availableTools = []) {
    try {
      // 获取或创建对话上下文
      const context = this.getConversationContext(conversationId);
      
      // 添加用户消息到上下文
      context.messages.push({
        role: 'user',
        content: message
      });

      // 构建系统提示词
      const systemPrompt = llmClient.buildSystemPrompt('', availableTools);
      
      // 准备消息数组
      const messages = [
        { role: 'system', content: systemPrompt },
        ...context.messages
      ];

      // 准备工具定义
      const tools = this.formatToolsForLLM(availableTools);

      log.debug('处理用户消息', { 
        conversationId, 
        messageLength: message.length,
        contextSize: context.messages.length,
        toolCount: tools.length
      });

      // 调用LLM
      const response = await llmClient.chat(messages, { 
        tools: tools.length > 0 ? tools : null 
      });

      const choice = response.choices[0];
      const assistantMessage = choice.message;

      // 处理响应
      if (assistantMessage.tool_calls && assistantMessage.tool_calls.length > 0) {
        // 有工具调用
        return {
          type: 'tool_calls',
          message: assistantMessage,
          toolCalls: assistantMessage.tool_calls
        };
      } else {
        // 普通文本响应
        context.messages.push(assistantMessage);
        
        return {
          type: 'text',
          content: assistantMessage.content,
          finishReason: choice.finish_reason
        };
      }
    } catch (error) {
      log.error('处理用户消息失败', error);
      throw error;
    }
  }

  /**
   * 流式处理用户消息
   * @param {string} message - 用户消息
   * @param {string} conversationId - 对话ID
   * @param {Array} availableTools - 可用工具列表
   * @returns {Promise<AsyncIterable>} 流式响应
   */
  async processMessageStream(message, conversationId, availableTools = []) {
    try {
      // 获取或创建对话上下文
      const context = this.getConversationContext(conversationId);
      
      // 添加用户消息到上下文
      context.messages.push({
        role: 'user',
        content: message
      });

      // 构建系统提示词
      const systemPrompt = llmClient.buildSystemPrompt('', availableTools);
      
      // 准备消息数组
      const messages = [
        { role: 'system', content: systemPrompt },
        ...context.messages
      ];

      // 准备工具定义
      const tools = this.formatToolsForLLM(availableTools);

      log.debug('流式处理用户消息', { 
        conversationId, 
        messageLength: message.length,
        contextSize: context.messages.length,
        toolCount: tools.length
      });

      // 调用LLM流式接口
      const stream = await llmClient.chatStream(messages, { 
        tools: tools.length > 0 ? tools : null 
      });

      return stream;
    } catch (error) {
      log.error('流式处理用户消息失败', error);
      throw error;
    }
  }

  /**
   * 处理多个工具调用结果（支持返回新的tool_calls）
   * @param {string} conversationId - 对话ID
   * @param {Object} assistantMessage - 助手消息（包含tool_calls）
   * @param {Array} toolResults - 工具执行结果数组
   * @returns {Promise<Object>} 处理结果（可能包含新的tool_calls或最终文本）
   */
  async processToolResults(conversationId, assistantMessage, toolResults) {
    try {
      const context = this.getConversationContext(conversationId);
      
      // 添加工具调用消息到上下文
      if (!context.messages[context.messages.length - 1]?.tool_calls) {
        context.messages.push({
          role: 'assistant',
          content: assistantMessage.content,
          tool_calls: assistantMessage.tool_calls
        });
      }

      // 添加所有工具结果到上下文
      for (const { toolCall, result } of toolResults) {
        const resultString = typeof result === 'object' ? JSON.stringify(result) : String(result);
        const toolResultMessage = llmClient.formatToolResult(toolCall, resultString);
        context.messages.push(toolResultMessage);
      }

      // 准备消息数组
      const messages = [
        { role: 'system', content: llmClient.buildSystemPrompt('', this.formatToolsForLLM(this.getAvailableTools())) },
        ...context.messages
      ];

      // 准备工具定义（以支持新的工具调用）
      const availableTools = this.getAvailableTools();
      const tools = this.formatToolsForLLM(availableTools);

      log.debug('处理工具调用结果', { 
        conversationId, 
        toolResultsCount: toolResults.length,
        contextSize: context.messages.length,
        toolsAvailable: tools.length
      });

      // 再次调用LLM获取响应
      const response = await llmClient.chat(messages, { 
        tools: tools.length > 0 ? tools : null 
      });
      
      const choice = response.choices[0];
      const newAssistantMessage = choice.message;

      // 检查是否有新的工具调用
      if (newAssistantMessage.tool_calls && newAssistantMessage.tool_calls.length > 0) {
        // 返回新的工具调用
        return {
          type: 'tool_calls',
          message: newAssistantMessage,
          toolCalls: newAssistantMessage.tool_calls
        };
      } else {
        // 返回最终文本响应
        context.messages.push(newAssistantMessage);
        
        return {
          type: 'text',
          content: newAssistantMessage.content,
          finishReason: choice.finish_reason
        };
      }
    } catch (error) {
      log.error('处理工具调用结果失败', error);
      throw error;
    }
  }

  /**
   * 获取可用工具列表（从 MCP 客户端）
   * @returns {Array} 工具列表
   */
  getAvailableTools() {
    const mcpClient = require('../utils/mcp-client');
    return mcpClient.getAvailableTools();
  }

  /**
   * 获取对话上下文
   * @param {string} conversationId - 对话ID
   * @returns {Object} 对话上下文
   */
  getConversationContext(conversationId) {
    if (!this.conversationContexts.has(conversationId)) {
      this.conversationContexts.set(conversationId, {
        id: conversationId,
        messages: [],
        createdAt: new Date(),
        lastActivity: new Date()
      });
    }
    
    const context = this.conversationContexts.get(conversationId);
    context.lastActivity = new Date();
    
    return context;
  }

  /**
   * 清理对话上下文
   * @param {string} conversationId - 对话ID
   */
  clearConversationContext(conversationId) {
    this.conversationContexts.delete(conversationId);
    log.debug('清理对话上下文', { conversationId });
  }

  /**
   * 格式化工具定义为LLM可用格式
   * @param {Array} tools - 工具列表
   * @returns {Array} 格式化的工具定义
   */
  formatToolsForLLM(tools) {
    return tools.map(tool => ({
      type: 'function',
      function: {
        name: tool.name,
        description: tool.description,
        parameters: tool.parameters || {
          type: 'object',
          properties: {},
          required: []
        }
      }
    }));
  }

  /**
   * 定期清理过期的对话上下文
   */
  cleanupExpiredContexts() {
    const now = new Date();
    const expireTime = 30 * 60 * 1000; // 30分钟过期

    for (const [conversationId, context] of this.conversationContexts.entries()) {
      if (now - context.lastActivity > expireTime) {
        this.conversationContexts.delete(conversationId);
        log.debug('清理过期对话上下文', { conversationId });
      }
    }
  }
}

// 创建单例实例
const llmService = new LLMService();

// 定期清理过期上下文
setInterval(() => {
  llmService.cleanupExpiredContexts();
}, 10 * 60 * 1000); // 每10分钟清理一次

module.exports = llmService;